package com.punch.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.punch.common.dto.system.semester.SemesterDTO;
import com.punch.common.dto.user.user.RedisUserDTO;
import com.punch.common.enums.user.role.UserRoleEnum;
import com.punch.common.exception.BusinessException;
import com.punch.common.exception.CommonExceptionEnum;
import com.punch.common.page.PageInfo;
import com.punch.common.query.syste.SemesterQueryInfo;
import com.punch.common.simple.redis.utils.UserUtil;
import com.punch.common.tools.BasePage;
import com.punch.common.vo.system.SemesterVO;
import com.punch.system.exception.SysExceptionEnum;
import com.punch.system.mapper.SemesterMapper;
import com.punch.system.model.SysSemester;
import com.punch.system.service.NationAreaService;
import com.punch.system.service.SemesterService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 学期表 服务实现类
 * </p>
 *
 * @author wjj
 * @since 2020-11-25
 */
@Service
public class SemesterServiceImpl extends ServiceImpl<SemesterMapper, SysSemester> implements SemesterService {

    @Resource
    private NationAreaService areaService;

    /**
     * 学期列表
     *
     * @param semesterQueryInfo 学期查询条件
     * @return PageInfo<SemesterVO>
     */
    @Override
    public PageInfo<SemesterVO> listSemester(SemesterQueryInfo semesterQueryInfo) {
        //查询自己与子地区
        Integer currentAreaId = semesterQueryInfo.getCurrentAreaId();
        List<Integer> childAreaIdList = areaService.listFeignChildId(currentAreaId);
        if (CollUtil.isEmpty(childAreaIdList)) {
            childAreaIdList = new ArrayList<>();
        }
        childAreaIdList.add(currentAreaId);
        semesterQueryInfo.setChildAreaIdList(childAreaIdList);
        return BasePage.queryBasePage(semesterQueryInfo, params -> baseMapper.queryCount(params),
                params -> baseMapper.queryList(params));
    }

    /**
     * 新增学期
     *
     * @param semesterDTO 新增学期
     * @return semesterId
     * @author wujj
     * @since 2020/6/4 19:33
     */
    @Override
    public Long saveSemester(SemesterDTO semesterDTO) {
        RedisUserDTO loginUser = UserUtil.getLoginUser();
        //只有教育局才能创建
        if (UserRoleEnum.EDUCATION.getCode() != loginUser.getRoleId()) {
            throw new BusinessException(SysExceptionEnum.ONLY_EDU_CAN_CREATE);
        }
        //同一年的上学期/下学期只有一条记录,只需要验证学期开始时间即可
        //如果月份在1-6则为上学期,7-12则为下学期
        LocalDateTime semesterStart = semesterDTO.getSemesterStart();
        QueryWrapper<SysSemester> queryWrapper = new QueryWrapper<>();
        Integer type = 0;
        checkSemester(semesterStart, queryWrapper, type);
        SysSemester sysSemester = new SysSemester();
        sysSemester.setSemesterName(semesterDTO.getSemesterName());
        sysSemester.setSemesterStart(semesterDTO.getSemesterStart());
        sysSemester.setSemesterEnd(semesterDTO.getSemesterEnd());
        sysSemester.setCreateId(loginUser.getUserId());
        sysSemester.setType(type);
        sysSemester.setAreaId(loginUser.getAreaId());
        sysSemester.setAreaName(loginUser.getAreaName());
        if (!save(sysSemester)) {
            throw new BusinessException(CommonExceptionEnum.SAVE_ERROR);
        }
        return sysSemester.getId();
    }

    /**
     * 修改学期
     *
     * @param semesterDTO 学期表单
     * @return semesterId
     * @author wujj
     * @since 2020/6/4 19:33
     */
    @Override
    public Long updateSemester(SemesterDTO semesterDTO) {
        //同一年的上学期/下学期只有一条记录,只需要验证学期开始时间即可
        //如果月份在1-6则为上学期,7-12则为下学期
        QueryWrapper<SysSemester> queryWrapper = new QueryWrapper<>();
        Integer type = 0;
        LocalDateTime semesterStart = semesterDTO.getSemesterStart();
        checkSemester(semesterStart, queryWrapper, type);
        SysSemester sysSemester = new SysSemester();
        sysSemester.setId(semesterDTO.getSemesterId());
        sysSemester.setSemesterName(semesterDTO.getSemesterName());
        sysSemester.setSemesterStart(semesterDTO.getSemesterStart());
        sysSemester.setSemesterEnd(semesterDTO.getSemesterEnd());
        sysSemester.setType(type);
        if (!updateById(sysSemester)) {
            throw new BusinessException(CommonExceptionEnum.UPDATE_ERROR);
        }
        return semesterDTO.getSemesterId();
    }

    /**
     * 删除学期
     *
     * @param semesterId 学期id
     * @return long
     */
    @Override
    public Long deleteSemester(Long semesterId) {
        if (!removeById(semesterId)) {
            throw new BusinessException(CommonExceptionEnum.DELETE_ERROR);
        }
        return semesterId;
    }

    private void checkSemester(LocalDateTime semesterStart, QueryWrapper<SysSemester> queryWrapper, Integer type) {
        if (semesterStart.getMonthValue() > 1 && semesterStart.getMonthValue() < 6) {
            LocalDateTime one = LocalDateTime.of(semesterStart.getYear(), 1, 1, 0, 0, 0);
            LocalDateTime six = LocalDateTime.of(semesterStart.getYear(), 6, 1, 0, 0, 0);
            queryWrapper.lambda().gt(SysSemester::getSemesterStart, one)
                    .lt(SysSemester::getSemesterStart, six);
            one = six = null;
        }
        if (semesterStart.getMonthValue() > 7 && semesterStart.getMonthValue() < 12) {
            type = 1;
            LocalDateTime seven = LocalDateTime.of(semesterStart.getYear(), 7, 1, 0, 0, 0);
            LocalDateTime twelve = LocalDateTime.of(semesterStart.getYear(), 12, 1, 0, 0, 0);
            queryWrapper.lambda().gt(SysSemester::getSemesterStart, seven)
                    .lt(SysSemester::getSemesterStart, twelve);
            seven = twelve = null;
        }
        if (getOne(queryWrapper) != null) {
            throw new BusinessException(SysExceptionEnum.SEMESTER_IS_EXIST);
        }
    }
}
